package com.lb.shopguide.ui.view.chart;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;


import com.lb.shopguide.R;
import com.lb.shopguide.entity.local.PieBean;
import com.lb.shopguide.entity.local.PiePoint;

import java.util.ArrayList;

/**
 * Created by gjy on 16/7/4.
 */

public class LbCircleView extends View {

    private final String TAG = "SuperCircleView";

    private int mViewWidth; //view的宽
    private int mViewHeight;    //view的高
    private int mViewCenterX;   //view宽的中心点
    private int mViewCenterY;   //view高的中心点
    private float mMinRadio; //最里面白色圆的半径
    private float mRingWidth; //圆环的宽度
    private int mMinCircleColor;    //最里面圆的颜色
    private Paint mPaint;
    private Paint mTextPaint;

    private RectF mCircleRectF; //圆环的矩形区域

    private float density;
    private float scaleDensity;
    private float fraction;

    private boolean animFlag;
    //    private int startAngle = 0;
    private ArrayList<PieBean> mList;
    private ArrayList<PiePoint> mListPoint;

    protected ValueAnimator mAnimator;//动画对象

    public LbCircleView(Context context) {
        this(context, null);
    }

    public LbCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LbCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LbCircleView);
        initParams(a, context);
        initPaint();
    }

    private void initParams(TypedArray a, Context context) {
        density = getResources().getDisplayMetrics().density / 2;
        scaleDensity = getResources().getDisplayMetrics().density / 2;
        animFlag = false;
        mListPoint = new ArrayList<>();
        mMinRadio = (int) (a.getInteger(R.styleable.LbCircleView_min_circle_radio, 400) * density);
        mRingWidth = a.getFloat(R.styleable.LbCircleView_ring_width, 40) * density;
        mMinCircleColor = a.getColor(R.styleable.LbCircleView_circle_color, context.getResources().getColor(R.color.white));
        a.recycle();
    }

    private void initPaint() {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setAntiAlias(true);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(1 * density);
    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mViewWidth = getMeasuredWidth();
        mViewHeight = getMeasuredHeight();
        mViewCenterX = mViewWidth / 2;
        mViewCenterY = mViewHeight / 2;
        mCircleRectF = new RectF(mViewCenterX - mMinRadio - mRingWidth, mViewCenterY - mMinRadio - mRingWidth, mViewCenterX + mMinRadio + mRingWidth, mViewCenterY + mMinRadio + mRingWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mList == null) {
            return;
        }
        mListPoint = new ArrayList<>();
        drawCircle(canvas);
    }

    public void setData(ArrayList<PieBean> list) {
        mList = list;
        startAnim();
    }

    private void drawCircle(Canvas canvas) {
        int startAngle = 0;
        for (int i = 0; i < mList.size(); i++) {
            PieBean pieBean = mList.get(i);
            mPaint.setColor(pieBean.getColor());
            canvas.drawArc(mCircleRectF, startAngle, pieBean.getValue() * fraction, true, mPaint);
            startAngle = startAngle + Math.round(pieBean.getValue() * fraction);
            if (fraction == 1.0f) {
                drawLineAndText(canvas, startAngle, Math.round(pieBean.getValue()), pieBean.getTopText(), pieBean.getBottomText());
            }
        }
        mPaint.setColor(mMinCircleColor);
        canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);
    }

    private void drawLineAndText(Canvas canvas, int startAngle, int sweepAngle, String topText, String bottomText) {
        //画圆
        float pointRadio = mRingWidth + mMinRadio + 20 * density;
        int angle = sweepAngle / 2 + startAngle;
        float yAxis = (float) (Math.sin(Math.PI * angle / 180) * (pointRadio)) + mViewCenterY;
        float xAxis = (float) (Math.cos(Math.PI * angle / 180) * (pointRadio)) + mViewCenterX;
        PiePoint point = new PiePoint(xAxis, yAxis);
        if (checkNear(point)) {
            // TODO: 2018/3/1 需要优化
            drawLineAndText(canvas, startAngle, sweepAngle + 10, topText, bottomText);
            return;
        }
        mListPoint.add(point);

        canvas.drawCircle(xAxis, yAxis, 4 * density, mPaint);
        mTextPaint.setTextSize(18 * scaleDensity);
        //画线
        int biasLineLength = (int) (14 * density);
        int horLineLength = (int) (140 * density);
        //分为四个象限
        float targetY;//圆圈的y
        float targetX;//圆圈的x
        float topTextWidth = mTextPaint.measureText(topText);
        float bottomTextWidth = mTextPaint.measureText(bottomText);
        if (angle > 360) {
            angle -= 360;
        }
        if (angle >= 270 && angle <= 360) {//第四象限
            if (angle <= 315) {
                targetY = yAxis - biasLineLength;
                targetX = xAxis + biasLineLength;
                canvas.drawLine(xAxis, yAxis, targetX, targetY, mPaint);
            } else {
                targetY = yAxis;
                targetX = xAxis;
            }
            canvas.drawLine(targetX, targetY, targetX + horLineLength, targetY, mPaint);
            drawTopText(canvas, targetX + horLineLength - topTextWidth, targetY, topText);
            drawBottomText(canvas, targetX + horLineLength - bottomTextWidth, targetY, bottomText);
        } else if (angle >= 0 && angle < 90) {//第一象限
            if (angle >= 45) {
                targetY = yAxis + biasLineLength;
                targetX = xAxis + biasLineLength;
                canvas.drawLine(xAxis, yAxis, targetX, targetY, mPaint);
            } else {
                targetY = yAxis;
                targetX = xAxis;
            }
            canvas.drawLine(targetX, targetY, targetX + horLineLength, targetY, mPaint);
            drawTopText(canvas, targetX + horLineLength - topTextWidth, targetY, topText);
            drawBottomText(canvas, targetX + horLineLength - bottomTextWidth, targetY, bottomText);
        } else if (angle >= 90 && angle < 180) {//第二象限
            if (angle >= 45) {
                targetY = yAxis + biasLineLength;
                targetX = xAxis - biasLineLength;
                canvas.drawLine(xAxis, yAxis, targetX, targetY, mPaint);
            } else {
                targetY = yAxis;
                targetX = xAxis;
            }
            canvas.drawLine(targetX, targetY, targetX - horLineLength, targetY, mPaint);
            drawTopText(canvas, targetX - horLineLength, targetY, topText);
            drawBottomText(canvas, targetX - horLineLength, targetY, bottomText);
        } else if (angle >= 180 && angle < 270) {//第三象限
            if (angle >= 45) {
                targetY = yAxis - biasLineLength;
                targetX = xAxis - biasLineLength;
                canvas.drawLine(xAxis, yAxis, targetX, targetY, mPaint);
            } else {
                targetY = yAxis;
                targetX = xAxis;
            }
            canvas.drawLine(targetX, targetY, targetX - horLineLength, targetY, mPaint);
            drawTopText(canvas, targetX - horLineLength, targetY, topText);
            drawBottomText(canvas, targetX - horLineLength, targetY, bottomText);
        }

    }


    private void drawTopText(Canvas canvas, float baseX, float baseY, String text) {
        //画文字
        mTextPaint.setColor(Color.rgb(119, 119, 119));
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
        float offY = fontTotalHeight / 2 - fontMetrics.bottom;
        float newY = baseY - offY * density;

        canvas.drawText(text, baseX, newY, mTextPaint);
    }

    private void drawBottomText(Canvas canvas, float baseX, float baseY, String text) {
        //画文字
        mTextPaint.setColor(Color.rgb(119, 119, 119));

        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
        float offY = fontTotalHeight - fontMetrics.bottom;
        float newY = baseY + offY * 1.2f * density;

        canvas.drawText(text, baseX, newY, mTextPaint);
    }

    private boolean checkNear(PiePoint piePoint) {
        boolean flag = false;
        if (mListPoint.size() == 0) {
            return flag;
        }
        for (int i = 0; i < mListPoint.size(); i++) {
            double distance = getDistance(piePoint, mListPoint.get(i));
            double y = piePoint.getyAxis() - mListPoint.get(i).getyAxis();
            if (distance < 30.0 * density && Math.abs(y) < 30 * density) {
                flag = true;
            }
        }
        return flag;
    }

    private double getDistance(PiePoint pt1, PiePoint pt2) {
        double x = pt1.getxAxis() - pt2.getxAxis();
        double y = pt1.getyAxis() - pt2.getyAxis();
        return Math.sqrt(x * x + y * y);
    }

    protected void startAnim() {
        //动画正在运行的话，先stop吧。万一有人要使用新动画呢，（正经用户不会这么用。）
        stopAnim();

        mAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
        mAnimator.setInterpolator(new DecelerateInterpolator());
        mAnimator.setDuration(2000);
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                fraction = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        mAnimator.start();
    }

    /**
     * 停止动画
     */
    public void stopAnim() {
        if (null != mAnimator) {
            mAnimator.cancel();
        }
    }

}
